/*
https://flutter.cn/docs/get-started/flutter-for/android-devs

如何使用 Canvas 进行绘制？
在 Android 中，你可以使用 Canvas 和 Drawable 将图片和形状绘制到屏幕上。 Flutter 也有一个类似于 Canvas 的 API，因为它基于相同的底层渲染引擎 Skia。
因此，在 Flutter 中用画布 (canvas) 进行绘制对于 Android 开发者来说是一件非常熟悉的工作。

Flutter 有两个帮助你用画布 (canvas) 进行绘制的类： CustomPaint 和 CustomPainter，后者可以实现自定义的绘制算法。

如果想学习在 Flutter 中如何实现一个签名功能，可以查看 Collin 在 Custom Paint 上的回答。
 */
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';

void main() {
  runApp(const DemoApp());
}

class DemoApp extends StatelessWidget {
  const DemoApp({super.key});

  @override
  Widget build(BuildContext context) => MaterialApp(
        title: '',
        home: Scaffold(
          appBar: AppBar(title: const Text('使用 Canvas 进行绘制')),
          body: Center(
            child: Signature(),
          ),
        ),
      );
}

class Signature extends StatefulWidget {
  const Signature({super.key});

  @override
  State<StatefulWidget> createState() => SignatureState();
}

class SignatureState extends State<Signature> {
  List<Offset?> _points = <Offset>[];

  @override
  Widget build(BuildContext context) {
    return GestureDetector(//手势识别
      onPanUpdate: (details) {
        setState(() {
          RenderBox? referenceBox = context.findRenderObject() as RenderBox;
          Offset localPosition =
              referenceBox.globalToLocal(details.globalPosition);
          _points = List.from(_points)..add(localPosition);
        });
      },
      onPanEnd: (details) => _points.add(null),
      child: CustomPaint(
        painter: SignaturePainter(_points),
        size: Size.infinite,
      ),
    );
  }
}

class SignaturePainter extends CustomPainter {
  final List<Offset?> points;

  SignaturePainter(this.points);

  @override
  void paint(Canvas canvas, Size size) {
    var paint = Paint()
      ..color = Colors.black
      ..strokeCap = StrokeCap.round
      ..strokeWidth = 5.0;
    for (int i = 0; i < points.length - 1; i++) {
      if (points[i] != null && points[i + 1] != null) {
        canvas.drawLine(points[i]!, points[i + 1]!, paint);
      }
    }
  }

  @override
  bool shouldRepaint(covariant SignaturePainter oldDelegate) =>
      oldDelegate.points != points;
}
